<template>
  <a-card class="signin-card" :bordered="false">
    <!-- 头部区域 -->
    <div class="signin-header">
      <div class="header-content">
        <h2 class="month-title">{{ currentMonthName }} {{ currentYear }}</h2>
        <div class="points-display">
          <div class="points-badge">
            <StarFilled class="points-icon" />
            <span>{{ totalPoints }}</span>
          </div>
          <span class="points-label">当前积分</span>
        </div>
      </div>
      <div class="month-nav">
        <a-button shape="circle" size="small" @click="prevMonth" class="nav-btn">
          <template #icon><LeftOutlined /></template>
        </a-button>
        <a-button shape="circle" size="small" @click="nextMonth" class="nav-btn">
          <template #icon><RightOutlined /></template>
        </a-button>
      </div>
    </div>

    <!-- 日历区域 -->
    <div class="calendar-container">
      <!-- 星期标题 -->
      <div class="weekdays">
        <div v-for="day in weekdays" :key="day" class="weekday">{{ day }}</div>
      </div>

      <!-- 日期格子 -->
      <div class="days-grid">
        <div
            v-for="(day, index) in calendarDays"
            :key="index"
            :class="[
            'day-cell',
            {
              'current-month': day.inMonth,
              'today': day.isToday,
              'checked': day.isChecked,
              'disabled': !day.inMonth || day.isFuture,
              'weekend': day.isWeekend,
              'makeup': day.isMakeup
            }
          ]"
            @click="handleDayClick(day)"
        >
          <div class="day-content">
            <span class="day-number">{{ day.number }}</span>
            <div class="day-status">
              <CheckCircleFilled
                  v-if="day.isChecked && !day.isMakeup"
                  class="check-icon"
              />
              <ExclamationCircleFilled
                  v-if="day.isMakeup"
                  class="makeup-icon"
              />
              <div v-if="day.isToday && !day.isChecked" class="today-indicator"></div>
            </div>
            <div v-if="day.isChecked || day.isMakeup" class="day-points">
              +{{ day.isMakeup ? calculatePoints(day.date) : 5 }}
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 签到进度 -->
    <div class="progress-container">
      <div class="progress-header">
        <span class="progress-title">签到进度</span>
        <span class="progress-value">{{ checkedDaysCount }}/{{ daysInMonth }}天 ({{ progressPercentage }}%)</span>
      </div>
      <div class="progress-bar">
        <div
            class="progress-fill"
            :style="{ width: `${progressPercentage}%` }"
        ></div>
      </div>
    </div>

    <!-- 操作按钮 -->
    <div class="action-buttons">
      <a-button
          type="primary"
          shape="round"
          :disabled="todayChecked"
          @click="handleCheckInToday"
          class="checkin-btn"
      >
        <template #icon><CheckOutlined /></template>
        {{ todayChecked ? '今日已签到' : '立即签到' }}
        <span v-if="!todayChecked" class="btn-points">+5积分</span>
      </a-button>

      <a-button
          type="dashed"
          shape="round"
          @click="showMakeupModal = true"
          class="makeup-btn"
          :disabled="makeupDaysLeft <= 0"
      >
        <template #icon><HistoryOutlined /></template>
        补签
        <span class="btn-badge">{{ makeupDaysLeft }}次</span>
      </a-button>
    </div>

    <!-- 统计信息 -->
    <div class="stats-container">
      <div class="stat-item" v-for="stat in stats" :key="stat.label">
        <div class="stat-chart">
          <div class="chart-svg">
            <svg viewBox="0 0 36 36" class="circular-chart">
              <path class="circle-bg"
                    d="M18 2.0845
                  a 15.9155 15.9155 0 0 1 0 31.831
                  a 15.9155 15.9155 0 0 1 0 -31.831"
              />
              <path class="circle-fill"
                    :stroke-dasharray="`${stat.percentage}, 100`"
                    :stroke="stat.color"
                    d="M18 2.0845
                  a 15.9155 15.9155 0 0 1 0 31.831
                  a 15.9155 15.9155 0 0 1 0 -31.831"
              />
            </svg>
            <div class="chart-value">{{ stat.value }}</div>
          </div>
        </div>
        <div class="stat-label">{{ stat.label }}</div>
      </div>
    </div>

    <!-- 签到成功提示 -->
    <a-modal
        v-model:visible="showRewardModal"
        :footer="null"
        :closable="false"
        centered
        width="280px"
        class="reward-modal"
    >
      <div class="reward-content">
        <div class="reward-animation">
          <div class="confetti"></div>
          <div class="confetti"></div>
          <div class="confetti"></div>
          <div class="confetti"></div>
          <div class="confetti"></div>
          <div class="reward-icon">
            <CheckCircleFilled />
          </div>
        </div>
        <h3>签到成功</h3>
        <p class="reward-points">+{{ rewardPoints }} 积分</p>
        <a-button
            type="primary"
            block
            @click="showRewardModal = false"
            class="confirm-btn"
        >
          确定
        </a-button>
      </div>
    </a-modal>

    <!-- 补签弹窗 -->
    <a-modal
        v-model:visible="showMakeupModal"
        title="补签"
        centered
        width="280px"
        class="makeup-modal"
    >
      <div class="makeup-content">
        <a-alert
            message="每月可补签3次"
            type="info"
            show-icon
            class="makeup-alert"
        />

        <a-list :data-source="missedDays" size="small" class="makeup-list">
          <template #renderItem="{ item }">
            <a-list-item>
              <a-list-item-meta>
                <template #title>
                  <span class="makeup-date">{{ formatDisplayDate(item.date) }}</span>
                </template>
                <template #description>
                  <span class="makeup-day">{{ getWeekday(item.date) }}</span>
                </template>
              </a-list-item-meta>
              <template #actions>
                <div class="makeup-right">
                  <span class="makeup-points">+{{ item.points }}积分</span>
                  <a-button
                      type="link"
                      size="small"
                      @click="handleMakeup(item.date)"
                      :disabled="item.isFuture"
                      class="makeup-action-btn"
                  >
                    补签
                  </a-button>
                </div>
              </template>
            </a-list-item>
          </template>
        </a-list>
      </div>
    </a-modal>
  </a-card>
</template>

<script>
import {ref, computed, onMounted} from 'vue';
import {
  CheckCircleFilled,
  ExclamationCircleFilled,
  StarFilled,
  CheckOutlined,
  LeftOutlined,
  RightOutlined,
  HistoryOutlined
} from '@ant-design/icons-vue';

export default {
  components: {
    CheckCircleFilled,
    ExclamationCircleFilled,
    StarFilled,
    CheckOutlined,
    LeftOutlined,
    RightOutlined,
    HistoryOutlined
  },
  setup() {
    // 响应式数据
    const currentDate = ref(new Date());
    const checkedDates = ref([]);
    const makeupDates = ref([]);
    const streakDays = ref([]);
    const showRewardModal = ref(false);
    const showMakeupModal = ref(false);
    const rewardPoints = ref(0);
    const todayChecked = ref(false);
    const totalPoints = ref(156);
    const makeupLimit = 3;
    const usedMakeupCount = ref(1);

    // 星期显示
    const weekdays = ['日', '一', '二', '三', '四', '五', '六'];

    // 计算属性
    const currentYear = computed(() => currentDate.value.getFullYear());
    const currentMonth = computed(() => currentDate.value.getMonth());
    const currentMonthName = computed(() => {
      const months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
      return months[currentMonth.value];
    });

    const daysInMonth = computed(() => {
      return new Date(currentYear.value, currentMonth.value + 1, 0).getDate();
    });

    const firstDayOfMonth = computed(() => {
      return new Date(currentYear.value, currentMonth.value, 1).getDay();
    });

    const makeupDaysLeft = computed(() => makeupLimit - usedMakeupCount.value);

    const progressPercentage = computed(() => {
      return Math.round((checkedDaysCount.value / daysInMonth.value) * 100);
    });

    const missedDays = computed(() => {
      const today = new Date();
      const result = [];

      for (let day = 1; day <= daysInMonth.value; day++) {
        const date = new Date(currentYear.value, currentMonth.value, day);
        const dateStr = formatDate(date);

        if (date > today) continue;

        if (!checkedDates.value.includes(dateStr) && !makeupDates.value.includes(dateStr)) {
          result.push({
            date: dateStr,
            points: calculatePoints(date),
            isFuture: date > today
          });
        }
      }

      return result;
    });

    const calendarDays = computed(() => {
      const days = [];
      const today = new Date();
      const todayFormatted = formatDate(today);

      // 上个月的最后几天
      const prevMonthDays = firstDayOfMonth.value;
      const prevMonth = new Date(currentYear.value, currentMonth.value, 0);
      const daysInPrevMonth = prevMonth.getDate();

      for (let i = prevMonthDays - 1; i >= 0; i--) {
        const day = daysInPrevMonth - i;
        const date = new Date(currentYear.value, currentMonth.value - 1, day);
        days.push(createDayObject(day, date));
      }

      // 当前月的天数
      for (let day = 1; day <= daysInMonth.value; day++) {
        const date = new Date(currentYear.value, currentMonth.value, day);
        days.push(createDayObject(day, date));
      }

      // 下个月的前几天
      const totalCells = Math.ceil((days.length) / 7) * 7;
      const nextMonthDays = totalCells - days.length;

      for (let day = 1; day <= nextMonthDays; day++) {
        const date = new Date(currentYear.value, currentMonth.value + 1, day);
        days.push(createDayObject(day, date));
      }

      todayChecked.value = checkedDates.value.includes(todayFormatted) ||
          makeupDates.value.includes(todayFormatted);

      return days;
    });

    const checkedDaysCount = computed(() => {
      return calendarDays.value.filter(day =>
          day.inMonth && (day.isChecked || day.isMakeup)
      ).length;
    });

    const currentStreak = computed(() => {
      const allSignedDates = [...checkedDates.value, ...makeupDates.value].sort();
      let streak = 0;
      let lastDate = null;

      for (let i = allSignedDates.length - 1; i >= 0; i--) {
        const currentDate = new Date(allSignedDates[i]);

        if (!lastDate) {
          streak = 1;
          lastDate = currentDate;
          continue;
        }

        const prevDate = new Date(lastDate);
        prevDate.setDate(prevDate.getDate() - 1);

        if (formatDate(prevDate) === allSignedDates[i]) {
          streak++;
          lastDate = currentDate;
        } else {
          break;
        }
      }

      return streak;
    });

    const totalCheckedDays = computed(() =>
        checkedDates.value.length + makeupDates.value.length
    );

    const stats = computed(() => [
      {
        label: '连续签到',
        value: currentStreak.value,
        percentage: Math.min(100, (currentStreak.value / 7) * 100),
        color: '#4CAF50'
      },
      {
        label: '本月签到',
        value: checkedDaysCount.value,
        percentage: progressPercentage.value,
        color: '#2196F3'
      },
      {
        label: '总签到',
        value: totalCheckedDays.value,
        percentage: Math.min(100, (totalCheckedDays.value / 100) * 100),
        color: '#FF9800'
      }
    ]);

    // 方法
    function formatDate(date) {
      return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
    }

    function formatDisplayDate(dateStr) {
      const date = new Date(dateStr);
      return `${date.getMonth() + 1}月${date.getDate()}日`;
    }

    function getWeekday(dateStr) {
      const date = new Date(dateStr);
      return `星期${['日', '一', '二', '三', '四', '五', '六'][date.getDay()]}`;
    }

    function createDayObject(day, date) {
      const dateStr = formatDate(date);
      const today = new Date();
      const todayFormatted = formatDate(today);
      const dayOfWeek = date.getDay();

      return {
        number: day,
        date: date,
        inMonth: date.getMonth() === currentMonth.value,
        isToday: dateStr === todayFormatted,
        isChecked: checkedDates.value.includes(dateStr),
        isMakeup: makeupDates.value.includes(dateStr),
        isWeekend: dayOfWeek === 0 || dayOfWeek === 6,
        isFuture: date > today
      };
    }

    function calculatePoints(date) {
      const today = new Date();
      const diffTime = today - date;
      const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
      return Math.max(1, 5 - diffDays);
    }

    function prevMonth() {
      currentDate.value = new Date(currentYear.value, currentMonth.value - 1, 1);
    }

    function nextMonth() {
      currentDate.value = new Date(currentYear.value, currentMonth.value + 1, 1);
    }

    function handleDayClick(day) {
      if (!day.inMonth || day.isFuture) return;
      if (day.isChecked || day.isMakeup) return;
      if (day.isToday) {
        handleCheckInToday();
        return;
      }
      showMakeupModal.value = true;
    }

    function handleCheckInToday() {
      const today = new Date();
      const todayFormatted = formatDate(today);

      if (!checkedDates.value.includes(todayFormatted)) {
        checkedDates.value.push(todayFormatted);
        updateStreak(today);
        addPoints(5);
        showRewardNotification(5);
        todayChecked.value = true;
      }
    }

    function handleMakeup(dateStr) {
      if (usedMakeupCount.value >= makeupLimit) return;

      const date = new Date(dateStr);
      const today = new Date();

      if (date > today) return;
      if (checkedDates.value.includes(dateStr)) return;

      makeupDates.value.push(dateStr);
      usedMakeupCount.value++;
      updateStreak(date);

      const points = calculatePoints(date);
      addPoints(points);
      showRewardNotification(points, true);

      if (dateStr === formatDate(today)) {
        todayChecked.value = true;
      }

      showMakeupModal.value = false;
    }

    function updateStreak(date) {
      const dateStr = formatDate(date);
      const yesterday = new Date(date);
      yesterday.setDate(yesterday.getDate() - 1);
      const yesterdayStr = formatDate(yesterday);

      const allSignedDates = [...checkedDates.value, ...makeupDates.value];

      if (allSignedDates.includes(yesterdayStr)) {
        if (!streakDays.value.includes(yesterdayStr)) {
          streakDays.value.push(yesterdayStr);
        }
        streakDays.value.push(dateStr);
      } else {
        streakDays.value = [dateStr];
      }
    }

    function addPoints(points) {
      totalPoints.value += points;
    }

    function showRewardNotification(points) {
      rewardPoints.value = points;
      showRewardModal.value = true;
    }

    // 初始化数据
    onMounted(() => {
      const today = new Date();
      const yesterday = new Date(today);
      yesterday.setDate(yesterday.getDate() - 1);
      const twoDaysAgo = new Date(yesterday);
      twoDaysAgo.setDate(twoDaysAgo.getDate() - 1);
      const threeDaysAgo = new Date(twoDaysAgo);
      threeDaysAgo.setDate(threeDaysAgo.getDate() - 1);

      checkedDates.value = [
        formatDate(threeDaysAgo),
        formatDate(twoDaysAgo),
        formatDate(yesterday)
      ];

      makeupDates.value = [formatDate(threeDaysAgo)];
      usedMakeupCount.value = 1;

      streakDays.value = [
        formatDate(threeDaysAgo),
        formatDate(twoDaysAgo),
        formatDate(yesterday)
      ];

      todayChecked.value = checkedDates.value.includes(formatDate(today)) ||
          makeupDates.value.includes(formatDate(today));
    });

    return {
      currentDate,
      checkedDates,
      makeupDates,
      streakDays,
      showRewardModal,
      showMakeupModal,
      rewardPoints,
      todayChecked,
      totalPoints,
      makeupLimit,
      usedMakeupCount,
      weekdays,
      currentYear,
      currentMonth,
      currentMonthName,
      daysInMonth,
      firstDayOfMonth,
      makeupDaysLeft,
      progressPercentage,
      missedDays,
      calendarDays,
      checkedDaysCount,
      currentStreak,
      totalCheckedDays,
      stats,
      prevMonth,
      nextMonth,
      handleDayClick,
      handleCheckInToday,
      handleMakeup,
      formatDisplayDate,
      getWeekday,
      calculatePoints
    };
  }
};
</script>

<style scoped>
.signin-card {
  max-width: 360px;
  margin: 0 auto;
  border-radius: 16px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06);
  border: none;
  overflow: hidden;
  background: linear-gradient(135deg, #f9f9f9 0%, #ffffff 100%);
  transition: all 0.3s ease;
}

.signin-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding: 12px 16px 0;
}

.header-content {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.month-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #333;
  letter-spacing: 0.5px;
}

.points-display {
  display: flex;
  align-items: center;
  gap: 6px;
}

.points-badge {
  display: flex;
  align-items: center;
  gap: 4px;
  background: rgba(255, 152, 0, 0.1);
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 13px;
  color: #FF9800;
  font-weight: 500;
  border: 1px solid rgba(255, 152, 0, 0.2);
}

.points-icon {
  color: #FF9800;
  font-size: 13px;
}

.points-label {
  font-size: 11px;
  color: #888;
}

.month-nav {
  display: flex;
  gap: 6px;
}

.nav-btn {
  background: rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(0, 0, 0, 0.05);
  color: #666;
  transition: all 0.2s;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
  width: 28px;
  height: 28px;
}

.calendar-container {
  margin-bottom: 20px;
  padding: 0 12px;
}

.weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 8px;
  text-align: center;
}

.weekday {
  font-size: 12px;
  color: #666;
  font-weight: 500;
  padding: 2px 0;
}

.days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.day-cell {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(0, 0, 0, 0.03);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
}

.day-cell.current-month {
  background: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02);
}

.day-cell.disabled {
  color: #ddd;
  cursor: not-allowed;
  background: transparent;
  box-shadow: none;
  border-color: transparent;
}

.day-cell.today:not(.checked):not(.makeup) {
  background: rgba(33, 150, 243, 0.1);
  color: #2196F3;
  font-weight: 600;
  border-color: rgba(33, 150, 243, 0.2);
}

.day-cell.checked {
  background: rgba(76, 175, 80, 0.1);
  color: #4CAF50;
  font-weight: 600;
  border-color: rgba(76, 175, 80, 0.2);
}

.day-cell.makeup {
  background: rgba(255, 152, 0, 0.1);
  color: #FF9800;
  font-weight: 600;
  border-color: rgba(255, 152, 0, 0.2);
}

.day-cell.weekend:not(.checked):not(.makeup) {
  color: #666;
}

.day-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  position: relative;
  padding-top: 6px;
}

.day-number {
  font-size: 13px;
  font-weight: 500;
}

.day-status {
  margin-top: 1px;
}

.check-icon {
  font-size: 12px;
  color: #4CAF50;
}

.makeup-icon {
  font-size: 12px;
  color: #FF9800;
}

.today-indicator {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #2196F3;
}

.day-points {
  position: absolute;
  bottom: 3px;
  font-size: 9px;
  font-weight: 500;
  color: #fff;
  background: rgba(0, 0, 0, 0.3);
  padding: 0 3px;
  border-radius: 3px;
  line-height: 14px;
}

.progress-container {
  margin: 16px 12px;
  padding: 12px;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
}

.progress-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 13px;
}

.progress-title {
  color: #666;
  font-weight: 500;
}

.progress-value {
  color: #333;
  font-weight: 600;
}

.progress-bar {
  height: 6px;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 3px;
  overflow: hidden;
  position: relative;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #4CAF50, #8BC34A);
  border-radius: 3px;
  transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.action-buttons {
  display: flex;
  gap: 8px;
  margin: 16px 12px;
}

.checkin-btn {
  background: linear-gradient(135deg, #4CAF50, #66BB6A);
  border: none;
  flex: 1;
  height: 40px;
  font-weight: 500;
  font-size: 13px;
  box-shadow: 0 2px 8px rgba(76, 175, 80, 0.2);
  transition: all 0.3s;
}

.btn-points {
  margin-left: 4px;
  font-size: 11px;
  opacity: 0.8;
}

.makeup-btn {
  flex: 1;
  height: 40px;
  color: #FF9800;
  border-color: #FF9800;
  font-weight: 500;
  font-size: 13px;
  transition: all 0.3s;
}

.btn-badge {
  margin-left: 4px;
  background: rgba(255, 152, 0, 0.1);
  padding: 0 5px;
  border-radius: 8px;
  font-size: 11px;
  line-height: 16px;
}

.stats-container {
  display: flex;
  justify-content: space-between;
  padding: 12px;
  margin: 0 12px 12px;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
  padding: 0 6px;
}

.stat-chart {
  margin-bottom: 8px;
  position: relative;
}

.chart-svg {
  width: 50px;
  height: 50px;
}

.circular-chart {
  width: 100%;
  height: 100%;
}

.circle-bg {
  fill: none;
  stroke: #f0f0f0;
  stroke-width: 2.5;
}

.circle-fill {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
  animation: circleProgress 1.5s ease-out forwards;
  stroke-dashoffset: 25;
}

.chart-value {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 14px;
  font-weight: 600;
  color: #333;
}

.stat-label {
  font-size: 12px;
  color: #666;
}

.reward-modal :deep(.ant-modal-content) {
  border-radius: 14px;
  overflow: hidden;
  padding: 20px;
}

.reward-content {
  text-align: center;
  position: relative;
  z-index: 1;
}

.reward-animation {
  position: relative;
  width: 80px;
  height: 80px;
  margin: 0 auto 16px;
}

.reward-icon {
  position: relative;
  font-size: 50px;
  color: #4CAF50;
  z-index: 2;
}

.confetti {
  position: absolute;
  width: 6px;
  height: 6px;
  background: #FFC107;
  border-radius: 50%;
  animation: confettiFall 2s ease-out forwards;
  z-index: 1;
}

.reward-content h3 {
  margin: 0 0 6px;
  font-size: 18px;
  color: #333;
  font-weight: 600;
}

.reward-points {
  margin-bottom: 20px;
  font-size: 16px;
  color: #FF9800;
  font-weight: 600;
}

.confirm-btn {
  height: 38px;
  border-radius: 19px;
  background: linear-gradient(135deg, #4CAF50, #66BB6A);
  border: none;
  font-weight: 500;
  font-size: 13px;
  transition: all 0.3s;
}

.makeup-modal :deep(.ant-modal-content) {
  border-radius: 14px;
  overflow: hidden;
}

.makeup-modal :deep(.ant-modal-header) {
  border-bottom: none;
  padding: 20px 20px 0;
}

.makeup-modal :deep(.ant-modal-title) {
  text-align: center;
  font-weight: 600;
  font-size: 16px;
}

.makeup-modal :deep(.ant-modal-body) {
  padding: 12px 20px 20px;
}

.makeup-content {
  padding: 6px 0;
}

.makeup-alert {
  margin-bottom: 12px;
  border-radius: 6px;
  border: 1px solid rgba(24, 144, 255, 0.1);
  font-size: 12px;
}

.makeup-list :deep(.ant-list-item) {
  padding: 10px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  align-items: center;
}

.makeup-list :deep(.ant-list-item-meta) {
  align-items: center;
}

.makeup-date {
  font-weight: 500;
  color: #333;
  font-size: 13px;
}

.makeup-day {
  font-size: 11px;
  color: #888;
}

.makeup-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.makeup-points {
  color: #FF9800;
  font-weight: 500;
  font-size: 12px;
}

.makeup-action-btn {
  color: #2196F3;
  font-weight: 500;
  font-size: 12px;
}

@keyframes circleProgress {
  0% {
    stroke-dasharray: 0, 100;
  }
}

@keyframes confettiFall {
  0% {
    transform: translateY(0) rotate(0deg);
    opacity: 1;
  }
  100% {
    transform: translateY(80px) rotate(360deg);
    opacity: 0;
  }
}
</style>
